/*
 * @Author: Wangjun
 * @Date: 2021-05-15 22:43:19
 * @LastEditTime: 2023-10-24 15:06:36
 * @LastEditors: Wangjun
 * @Description:
 * @FilePath: \golib\autoroute\defaulter\system.go
 * hnxr
 */
package defaulter

import (
	"goversion"
	"io"
	"os"
	"path/filepath"
	"strings"

	"gitee.com/haodreams/golib/autoroute/controller"
	"gitee.com/haodreams/golib/estring"
	"gitee.com/haodreams/golib/logs"
	"gitee.com/haodreams/golib/targz"
	"gitee.com/haodreams/libs/easy"
	"gitee.com/haodreams/libs/ezip"
	"gitee.com/haodreams/libs/routine"
	"gitee.com/haodreams/libs/sliceutil"
	"gitee.com/haodreams/libs/utils"
)

var defaultListDir = "./" //默认需要显示的目录
/**
 * @description: 设置默认的dir目录
 * @param {string} dir
 * @return {*}
 */
func SetDefaultListDir(dir string) {
	if !(strings.HasSuffix(dir, "/") || strings.HasSuffix(dir, "\\")) {
		dir += "/"
	}
	defaultListDir = dir
}

// SystemController 授权相关的操作
type SystemController struct {
	controller.Controller
}

// Version 获取版本信息
func (m *SystemController) Version() {
	version := goversion.Info()
	if version == "" {
		version = "无版本信息"
	}
	m.Msg(version)
}

// Exit 退出程序，程序有看门狗启动
func (m *SystemController) Exit() {
	logs.Info("==============程序手动停止运行===============")
	logs.Info("控制停止的服务器地址:", m.Request.RemoteAddr)
	logs.Info("============================APP EXIT============================")
	m.Msg("OK")
	routine.Stop()
}

// Upload 文件上传
func (m *SystemController) Upload() {
	if m.IsPost() {
		header, err := m.FormFile("file")
		if err != nil {
			m.Error(err.Error())
			return
		}
		dst := header.Filename
		fileName := filepath.Base(dst)
		f, err := header.Open()
		if err != nil {
			m.Error(err.Error())
			return
		}

		defer f.Close()

		if _, err := os.Stat("temp"); err != nil {
			os.MkdirAll("temp", 0755)
		}

		lf, err := os.Create("temp/" + fileName)
		if err != nil {
			logs.Error(err.Error())
			m.Error(err.Error())
			return
		}

		defer lf.Close()

		size, _ := io.Copy(lf, f)
		msg := estring.FormatSize(size)
		m.Msg("上传成功， 上传大小:" + msg)
		return
	}
	html := `<!DOCTYPE html>
	<html> <head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>upload file</title>
	</head><body><form action="/v1/system/upload" method="post" enctype="multipart/form-data">
	<input type="file" name="file" value="" /> 	<input type="submit" name="submit" />
	</form> </body></html>
	`
	m.Writer.Header().Add("Content-Type", "text/html")
	m.Writer.WriteHeader(200)
	m.Writer.Write([]byte(html))
}

func (m *SystemController) Upgrade() {
	if m.IsPost() {
		header, err := m.FormFile("file")
		if err != nil {
			m.Error(err.Error())
			return
		}
		dst := header.Filename
		fileName := filepath.Base(dst)
		f, err := header.Open()
		if err != nil {
			m.Error(err.Error())
			return
		}

		defer f.Close()

		if _, err := os.Stat("temp"); err != nil {
			os.MkdirAll("temp", 0755)
		}

		lf, err := os.Create("temp/" + fileName)
		if err != nil {
			logs.Error(err.Error())
			m.Error(err.Error())
			return
		}

		size, _ := io.Copy(lf, f)
		lf.Close()
		msg := estring.FormatSize(size)

		tmpPath := "temp/upgrade"
		os.RemoveAll(tmpPath)
		os.MkdirAll(tmpPath, 0755)
		switch {
		case strings.HasSuffix(fileName, ".tar.gz"):
			err = targz.Decode("temp/"+fileName, tmpPath)
			if err != nil {
				m.Msg("更新失败," + err.Error())
				return
			}
		case strings.HasSuffix(fileName, ".zip"):
			err = ezip.Decompress("temp/"+fileName, tmpPath, nil)
			if err != nil {
				m.Msg("更新失败," + err.Error())
				return
			}
		default:
			m.Msg("不支持的升级包")
			return
		}
		name := filepath.Base(os.Args[0])
		utils.Move(tmpPath+"/"+name, ".")
		os.Chmod(name, os.ModePerm)

		m.Msg("更新完成 更新大小:" + msg)
		return
	}
	html := `<!DOCTYPE html>
	<html> <head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>系统更新</title>
	</head><body><form action="/v1/system/Upgrade" method="post" enctype="multipart/form-data">
	<input type="file" name="file" value="" /> 	<input type="submit" name="submit" />
	</form> </body></html>
	`
	m.Writer.Header().Add("Content-Type", "text/html")
	m.Writer.WriteHeader(200)
	m.Writer.Write([]byte(html))
}

/**
 * @description: 显示默认的dir
 * @param {*}
 * @return {*}
 */
func (m *SystemController) ListDir() {
	params := m.GetParam()
	path := params.GetTrimString("path")
	path = defaultListDir + path

	fi, err := os.Stat(path)
	if err != nil {
		m.Error(err.Error())
		return
	}
	if fi.IsDir() {
		fis, err := os.ReadDir(path)
		if err != nil {
			m.Error(path)
			return
		}
		fs := make([]*easy.FileInfo, len(fis))
		idx := 0
		for _, f := range fis {
			f1 := new(easy.FileInfo)
			f1.Name = f.Name()
			f1.IsDir = f.IsDir()
			fi, err := f.Info()
			if err == nil {
				f1.Size = easy.BeautifySize(fi.Size())
				f1.ModTime = fi.ModTime().Unix()
				f1.Mode = fi.Mode().String()
			}

			fs[idx] = f1
			idx++
		}
		fs = fs[:idx]
		m.ToWhereSortPage(fs, nil, true, true)
		return
	}

	f, err := os.Open(path)
	if err != nil {
		m.Error(err.Error())
		return
	}
	defer f.Close()
	name := filepath.Base(path)
	m.Header("Content-Type", "application/octet-stream")
	m.Writer.Header().Add("Content-Disposition", "attachment; filename="+name)
	io.Copy(m.Writer, f)
}

/**
 * @description: 过滤 + 排序
 * @param {*} interface 需要过滤的数组
 * @return {*}
 */
func (m *SystemController) ToWhereSortPage(items interface{}, callback func(interface{}) interface{}, isReg ...bool) {
	//先过滤 后排序
	params := m.GetParam().GetMap()

	newItems := sliceutil.WhereMap(params, items, isReg...)
	sliceutil.OrderBy(newItems, params["sortKey"], params["sortOrder"])

	m.Page(newItems, callback)
}
